/*CopyRight 2015 By YXKJ Co., Ltd. All Rights Reserved.*/
package com.yx.system.menu;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 菜单解析器
 * 
 * @author zgq
 */
public class MenuParser {
	private MenuParser() {
	}

	private static MenuParser INSTANCE = new MenuParser();

	public static MenuParser getInstance() {
		return INSTANCE;
	}

	public List<Menu> parse(File file) throws SAXException, IOException,
			ParserConfigurationException, IntrospectionException,
			NumberFormatException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		List<Menu> menus = new ArrayList<Menu>(0);
		NodeList nodeList = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder().parse(file).getDocumentElement()
				.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			if ("menu".equals(node.getNodeName())) {
				Menu menu = new Menu();
				NamedNodeMap attributes = node.getAttributes();
				for (int j = 0; j < attributes.getLength(); j++) {
					String name = attributes.item(j).getNodeName();
					String value = attributes.item(j).getNodeValue();
					Method method = new PropertyDescriptor(name, Menu.class)
							.getWriteMethod();
					String type = method.getParameterTypes()[0].getName();
					if ("int".equals(type) || "java.lang.Integer".equals(type)) {
						if (value != null && !"".equals(value))
							method.invoke(menu, Integer.valueOf(value));
					} else
						method.invoke(menu, value);
				}
				menu.setItems(parseItem(node.getChildNodes()));
				menus.add(menu);
			}
		}
		return menus;
	}

	private List<Item> parseItem(NodeList nodeList)
			throws IntrospectionException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		List<Item> items = null;
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			if ("item".equals(node.getNodeName())) {
				Item item = new Item();
				NamedNodeMap attributes = node.getAttributes();
				for (int j = 0; j < attributes.getLength(); j++) {
					String name = attributes.item(j).getNodeName();
					String value = attributes.item(j).getNodeValue();
					Method method = new PropertyDescriptor(name, Item.class)
							.getWriteMethod();
					String type = method.getParameterTypes()[0].getName();
					if ("int".equals(type) || "java.lang.Integer".equals(type)) {
						if (value != null && !"".equals(value))
							method.invoke(item, Integer.valueOf(value));
					} else
						method.invoke(item, value);
				}
				item.setItems(parseItem(node.getChildNodes()));
				if (items == null)
					items = new ArrayList<Item>(0);
				items.add(item);
			}
		}
		return items;
	}
}
